home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / CNews / Source / misc / locknews.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-25  |  2.9 KB  |  135 lines

  1. /*
  2.  * locknews - lock the news system with newslock() and spawn a shell;
  3.  *    unlock with newsunlock() when the shell exits.
  4.  */
  5. #include <stdio.h>
  6. #include <signal.h>
  7. #include <sys/types.h>
  8. #include "news.h"
  9. #include "libc.h"
  10.  
  11. #ifndef SIGFUNCTYPE
  12. #define SIGFUNCTYPE void    /* was int */
  13. #endif
  14. typedef SIGFUNCTYPE (*sigtype)();
  15.  
  16. struct sigs {
  17.     sigtype    hup;
  18.     sigtype    intr;
  19.     sigtype    quit;
  20.     sigtype    term;
  21. };
  22.  
  23. /* imports */
  24. extern int optind;
  25. extern char *optarg;
  26. extern FILE *efopen();
  27.  
  28. /* exports */
  29. int debug;
  30. char *progname = "locknews";
  31.  
  32. /*
  33.  * main - parse arguments and handle options
  34.  */
  35. main(argc, argv)
  36. int argc;
  37. char *argv[];
  38. {
  39.     register int pid, kid;
  40.     register int c, errflg = 0;
  41.     int verbose = 0;
  42.     int status = -1;
  43.     struct sigs sigs;
  44.  
  45.     if (argc > 0)
  46.         progname = argv[0];
  47.     while ((c = getopt(argc, argv, "v")) != EOF)
  48.         switch (c) {
  49.         case 'v':
  50.             ++verbose;
  51.             break;
  52.         default:
  53.             errflg++;
  54.             break;
  55.         }
  56.     if (errflg || optind < argc) {
  57.         (void) fprintf(stderr, "usage: %s [-v]\n", progname);
  58.         exit(2);
  59.     }
  60.  
  61.     /*
  62.      * parent process needs to ignore at least keyboard signals
  63.      * to avoid leaving stray locks around by being killed.
  64.      */
  65.     sigs.hup =  signal(SIGHUP, SIG_IGN);
  66.     sigs.intr = signal(SIGINT, SIG_IGN);
  67.     sigs.quit = signal(SIGQUIT, SIG_IGN);
  68.     sigs.term = signal(SIGTERM, SIG_IGN);
  69.  
  70.     (void) newslock();
  71.     if (verbose) {
  72.         (void) fprintf(stderr,
  73.             "%s: you now have the news system locked\n", progname);
  74.         (void) fflush(stderr);
  75.     }
  76.  
  77.     pid = fork();
  78.     if (pid < 0)
  79.         errunlock("fork failed; unlocking news system", "");
  80.     if (pid == 0)
  81.         execsh(&sigs);            /* child */
  82.     while ((kid = wait(&status)) != pid && kid != -1)
  83.         ;
  84.  
  85.     (void) newsunlock();
  86.     if (verbose)
  87.         (void) fprintf(stderr,
  88.             "%s: the news system is now unlocked\n", progname);
  89.     exit(status | status>>8);
  90.     /* NOTREACHED */
  91. }
  92.  
  93. execsh(sigsp)
  94. register struct sigs *sigsp;            /* initial signal states */
  95. {
  96.     char *oldps, *newps, *shell;
  97.     static char defuxsh[] = "/bin/sh";    /* for Unix */
  98.     static char defp9sh[] = "/bin/rc";    /* for Plan 9 */
  99.     static char uxshpsname[] = "PS1";
  100.     static char p9shpsname[] = "prompt";
  101.  
  102.     /* the child, however, can safely be killed */
  103.     (void) signal(SIGHUP,  sigsp->hup);
  104.     (void) signal(SIGINT,  sigsp->intr);
  105.     (void) signal(SIGQUIT, sigsp->quit);
  106.     (void) signal(SIGTERM, sigsp->term);
  107.  
  108.     oldps = getenv(uxshpsname);
  109.     if (oldps == NULL)
  110.         oldps = "$ ";
  111.     newps = str3save(uxshpsname, "=: newslocked; ", oldps);
  112.     if (putenv(newps))
  113.         warning("can't add %s to environment", newps);
  114.  
  115.     oldps = getenv(p9shpsname);
  116.     if (oldps == NULL)
  117.         oldps = "; ";
  118.     newps = str3save(p9shpsname, "=newslocked=:; ", oldps);
  119.     if (putenv(newps))
  120.         warning("can't add %s to environment", newps);
  121.  
  122.     shell = getenv("SHELL");
  123.     if (shell != NULL) {
  124.         (void) execl(shell, shell, (char *)NULL);
  125.         warning("can't exec shell %s", shell);
  126.     } else {
  127.         (void) execl(defuxsh, defuxsh, (char *)NULL);
  128.         (void) execl(defp9sh, defp9sh, (char *)NULL);
  129.         warning("can't exec standard shells", "");
  130.     }
  131.     (void) fflush(stderr);
  132.     (void) _exit(127);
  133.     /* NOTREACHED */
  134. }
  135.